#! /usr/bin/env python
# -*- coding: utf-8 -*-
"""
geoloc.py
"""
import re, socket
from util.xplor import Xplorer
from util.functions import is_ip, decode
from urllib2 import URLError

def resolve_dns(string):
	if is_ip(string): return string
	try:
		string = socket.gethostbyname(string)
	except:
		string = ""
	return string

def dns(bot, evt, cmd):
	""".dns <ip|dns> [-rvs] — Returns info about an IP adress from dnsstuff.com."""
	a = resolve_dns(cmd.arguments)
	if a:
		info, html = Xplorer.get_request(dns.url % a, {"accept-encoding":"identity"})
		if html:
			txt= re.search("<code>(.*)</code>", html, re.S | re.M).group(1)
			items = re.findall("([^\r\n:]+)[?:] +([^\r\n]+)", txt)
			data = dict(items)
			if hasattr(cmd, "get_rng"):
				return "/".join(["&l;%s&N;" % x for x in data["Country IP Range"].split(" to ")])
			pxy = data["Known Proxy"]
			msg = "&B;IP:&N; {ip} | &B;IP Range:&N; {IPrange} | &B;Proxy:&N; {proxy} | &B;Country:&N; {country} | " \
				"&B;City:&N; {city} | &B;ASN:&N; {asn}".format(
				country = data["Country (per outside source)"],
				IPrange = "/".join(["&l;%s&N;" % x for x in data["Country IP Range"].split(" to ")]),
				city = data["City (per outside source)"],
				ip = data["IP address"],
				asn = data["ASN Name"],
				proxy = "&e;%s&N;" % pxy if pxy == "No" else "&r;%s&N;" % pxy,
				#not real: todo, get data about assignment from whatismyipaddress.com?
				static = "(static)" if "static" in data["Reverse DNS"] else "(dynamic)"
			)
			if cmd.opts["rvs"]: msg = msg.replace("|", "| &B;Reverse DNS:&N; %s |" % data["Reverse DNS"], 1)
			bot.reply(evt, msg)
dns.rule   = 'dnsstuff'
dns.aliases = "dns", "gloc"
dns.thread = True
#dns.url = "http://www.dnsstuff.com/tools/ipall.ch?domain="
dns.url = "http://private.dnsstuff.com/tools/ipall.ch?domain=%s"

def wimip(bot, evt, cmd):
	""".ip <ip|dns> [-rvs] [-rng] — Returns info about an IP adress from whatismyipaddress.com."""
	#based on https://gist.github.com/1746153
	ip = resolve_dns(cmd.arguments)
	if ip:
		try:
			info, html = Xplorer.get_url(wimip.url % ip, {"user-agent": "Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20120405 Firefox/14.0a1"})
		except URLError:
			#some problem occurs on 2012-04-28
			dns(bot, evt, cmd)
			return True
		if html:
			html = decode(html)
			clean = lambda x: re.sub("<[^>]+>([^<]+)<[^>]+>", r"\1", x)
			table = lambda x: re.search( r'<form action="/blacklist-check" method="POST"><table>(.+)</table></form>', x, re.S | re.M).group(1)
			key = lambda x: re.search( r'<th>(.+):</th>', x, re.M ).group(1)
			value = lambda x: re.search( r'<td>(.*)</td>', x, re.U ).group(1)
			dict1 = dict( [ (key(i), value(i)) for i in re.split('</tr>\s*<tr>', table(html)) ] )

			table = lambda x: re.search( r'</h2>\s+<table>\s+<tr>(.+)</tr>\s+</table>', x, re.S | re.M ).group(1)
			key = lambda x: re.search( r'<th>(.+):</th>', x, re.M ).group(1)
			value = lambda x: re.search( r'<td>(.+?)( <img |</td>)', x, re.U | re.S | re.M ).group(1)
			dict2 = dict( [ (key(i), value(i).strip()) for i in re.split('</tr>\s+<tr>', table(html)) ] )

			data = dict()
			data.update(dict1)
			data.update(dict2)

			assignment = bot._translate(evt, clean(data["Assignment"]))
			proxy = bot._translate(evt, clean(data['Services']))

			msg = u"&B;IP:&N; {ip} ({assignment}) | &B;Proxy:&N; {services} | &B;Country:&N; {country} | " \
				"&B;State/Region:&N; {state} | &B;City:&N; {city} | &B;ISP:&N; {ISP}".format(
				ip = data["IP"],
				country = data['Country'],
				state = data['State/Region'] if data.has_key("State/Region") else "",
				city =  data['City'] if data.has_key("City") else "",
				ISP = data["ISP"],
				services= u"&e;%s&N;" % proxy if data['Services'] == "None detected" else u"&r;%s&N;" % proxy,
				assignment = u"&o;%s&N;" % assignment if clean(data["Assignment"]) == "Static IP" else u"&p;%s&N;" % assignment
			)
			if cmd.opts["rvs"]: msg = msg.replace("|", "| &B;Reverse DNS:&N; %s |" % data["Hostname"], 1)
			if cmd.opts["rng"]:
				cmd.get_rng = True
				rng = dns(bot, evt, cmd)
				msg = msg.replace("| &B;Proxy:&N;", "| &B;IP Range:&N; %s | &B;Proxy:&N;" % rng, 1)
			bot.reply(evt, msg)
	else:
		bot.reply(evt, "IP was expected.")
wimip.rule="ip"
wimip.aliases = "geoloc"
wimip.thread=True
wimip.url = "http://whatismyipaddress.com/ip/%s"

def resolve(bot, evt, cmd):
	msg = ""
	try:
		ip = socket.gethostbyname(cmd.arguments)
		msg += "The URL %(params)s resolves to %(ip)s ( http://%(ip)s ). See also: [ http://www.ping.eu/ns_whois/?host=%(params)s ]." % {
			"ip":ip,
			"params":cmd.arguments
		}
	except:
	   msg+=" not reachable."
	if msg:
	   bot.reply(evt, msg)
resolve.rule="resolve"
